Skip to content

Skills

Skills are multi-function workflows that group related AIFunctions with shared instructions. When the agent activates a skill, it expands to reveal its constituent functions along with guidance on how to use them together.

What Are Skills?

Think of a skill as a "mode" the agent can enter:

Before activation:              After activation:
┌─────────────────────┐         ┌─────────────────────┐
│ Research Skill      │   ──►   │ WebSearch           │
│ "Deep research..."  │         │ CodeSearch          │
└─────────────────────┘         │ DocumentSearch      │
                                │                     │
                                │ Instructions:       │
                                │ 1. Search web first │
                                │ 2. Search code...   │
                                └─────────────────────┘

Key differences from plain AIFunctions:

  • Skills provide dual-context instructions (functionResult + systemPrompt) that guide the agent's workflow
  • Skills reference existing functions rather than defining new ones
  • Skills can include documents for additional context

Basic Usage

Mark a method with [Skill] and return a Skill object:

csharp
public class SearchTool
{
    [AIFunction]
    public async Task<string> WebSearch(string query) { /* ... */ }

    [AIFunction]
    public async Task<string> CodeSearch(string query) { /* ... */ }

    [Skill]
    public Skill ResearchSkill()
    {
        return SkillFactory.Create(
            name: "Research",
            description: "Deep research across web and code",
            functionResult: null,  // Auto-generated message is sufficient
            systemPrompt: @"
                RESEARCH WORKFLOW:
                1. Start with WebSearch for general context
                2. Use CodeSearch for implementation details
                3. Synthesize findings into a coherent summary",
            "SearchTool.WebSearch",
            "SearchTool.CodeSearch"
        );
    }
}

SkillFactory.Create()

Basic Signature

csharp
public static Skill Create(
    string name,              // Skill identifier (becomes the tool name)
    string description,       // Shown in tools list before activation
    string? functionResult,   // Ephemeral: shown once on activation (in conversation history)
    string? systemPrompt,     // Persistent: injected into system prompt every turn
    params string[] references  // "ToolName.FunctionName" format
)

Note: At least one of functionResult or systemPrompt must be provided.

With Options

csharp
public static Skill Create(
    string name,
    string description,
    string? functionResult,
    string? systemPrompt,
    SkillOptions? options,      // Documents and additional config
    params string[] references
)

Dual-Context Instructions

Skills use the same dual-context architecture as collapsed tools:

ParameterLocationLifetimeUse For
functionResultConversation historyOne-time on activationAdditional tips, status, environment info
systemPromptSystem promptEvery turn while activeWorkflow rules, constraints

Important: The system automatically generates a base activation message:

"{SkillName} skill activated. Available functions: {FunctionList}"

Your functionResult is appended to this auto-generated message. Don't duplicate the activation info—use it only for additional context like tips, environment state, or configuration details.

csharp
return SkillFactory.Create(
    name: "CodeReview",
    description: "Review code for quality",
    // Auto-generated: "CodeReview skill activated. Available functions: ReadFile, Analyze"
    functionResult: "Tip: Read the style guide document first.",  // Appended to auto message
    systemPrompt: @"
        REVIEW RULES:
        1. Always check for security issues first
        2. Note complexity and suggest simplifications
        3. Be constructive, not critical",  // Persistent
    "FileTool.ReadFile",
    "AnalysisTool.Analyze"
);

Function References

References use the format "ToolName.FunctionName":

csharp
return SkillFactory.Create(
    name: "DataAnalysis",
    description: "Analyze data from multiple sources",
    functionResult: null,  // Auto-generated message is sufficient
    systemPrompt: "Always validate data before analysis.",
    "DatabaseTool.Query",        // Reference function from another tool
    "FileSystemTool.ReadFile",   // Mix functions from different tools
    "SearchTool.WebSearch"       // Same tool is fine too
);

Important: Referenced functions must exist in registered tools. The source generator validates references at compile time when possible.


Skill Documents

Skills can include documents that provide additional context when activated.

SkillOptions

csharp
public class SkillOptions
{
    // Reference an existing document in the document store
    public SkillOptions AddDocument(
        string documentId,
        string? description = null)

    // Upload a document from a file
    public SkillOptions AddDocumentFromFile(
        string filePath,
        string description,
        string? documentId = null)

    // Upload a document from a URL
    public SkillOptions AddDocumentFromUrl(
        string url,
        string description,
        string? documentId = null)
}

Example with Documents

csharp
[Skill]
public Skill CodeReviewSkill()
{
    var options = new SkillOptions()
        .AddDocumentFromFile(
            "docs/code-standards.md",
            "Company coding standards and best practices")
        .AddDocument(
            "style-guide",
            "Official style guide");

    return SkillFactory.Create(
        name: "Code Review",
        description: "Review code for quality and standards compliance",
        functionResult: "Documents available: code-standards.md, style-guide",  // Additional context only
        systemPrompt: @"
            REVIEW WORKFLOW:
            1. Read the code-standards document first
            2. Check each file against the standards
            3. Provide specific, actionable feedback",
        options,
        "FileSystemTool.ReadFile",
        "FileSystemTool.ListDirectory"
    );
}

Document Store Setup

To use documents, register a document store with the agent:

csharp
var agent = new AgentBuilder()
    .WithDocumentStore(documentStore)
    .WithTool<ReviewTool>()
    .Build();

How Skill Expansion Works

When the agent "calls" a skill, the following happens:

  1. Container expands: The skill tool is replaced by its referenced functions
  2. FunctionResult shown: One-time orientation message appears in conversation
  3. SystemPrompt injected: Persistent instructions added to system prompt
  4. Documents available: Any attached documents become accessible
  5. Agent proceeds: Uses the expanded functions with instruction guidance
Agent's view before:
┌─────────────────────────────────┐
│ Tools: Research, SendEmail,... │
└─────────────────────────────────┘

Agent activates "Research" skill...

Agent's view after:
┌─────────────────────────────────┐
│ Tools: WebSearch, CodeSearch,  │
│        SendEmail,...           │
│                                │
│ Instructions:                  │
│ 1. Start with WebSearch...     │
└─────────────────────────────────┘

Requiring Permission

Skills can require user approval before activation:

csharp
[Skill]
[RequiresPermission]
public Skill DeploymentSkill()
{
    return SkillFactory.Create(
        name: "Deploy",
        description: "Deploy application to production",
        functionResult: "Target environment: production",  // Additional context only
        systemPrompt: "Always run tests before deploying. Never skip the build step.",
        "DeployTool.BuildApp",
        "DeployTool.RunTests",
        "DeployTool.Deploy"
    );
}

Typed Metadata

For compile-time validation, use the generic attribute:

csharp
public class SearchMetadata : IToolMetadata
{
    public bool HasMultipleProviders { get; set; }
    // Implementation...
}

public class SearchTool
{
    [Skill<SearchMetadata>]
    public Skill AdvancedResearch()
    {
        return SkillFactory.Create(
            name: "Advanced Research",
            description: "Research with multiple provider support",
            functionResult: null,  // Auto-generated message is sufficient
            systemPrompt: "Use multiple search providers for comprehensive results.",
            "SearchTool.WebSearch",
            "SearchTool.CodeSearch"
        );
    }
}

→ See 02.1.4 Tool Metadata.md for details.


Conditional Skills

Show or hide skills based on runtime conditions:

csharp
[Skill]
[ConditionalSkill("HasMultipleProviders")]
public Skill MultiProviderSearch()
{
    // Only visible when metadata.HasMultipleProviders is true
    return SkillFactory.Create(
        name: "Multi-Provider Search",
        description: "Search across multiple providers simultaneously",
        functionResult: null,  // Auto-generated message is sufficient
        systemPrompt: "Query all providers and synthesize results.",
        "SearchTool.TavilySearch",
        "SearchTool.BingSearch",
        "SearchTool.GoogleSearch"
    );
}

→ See 02.1.4 Tool Metadata.md for conditional registration details.


Skills vs Collapsed Toolkits

Both skills and collapsed toolkits group functions, but they serve different purposes:

AspectSkillCollapsed Toolkit
PurposeWorkflow with instructionsReduce context clutter
InstructionsYes, dual-context (functionResult + systemPrompt)Same dual-context
ScopeCan reference functions across toolkitsSingle toolkit only
DocumentsSupports attached documentsNo
ActivationExplicit "use this skill"Implicit on first function call

Use Skills when: You need to guide the agent through a multi-step workflow.

Use [Toolkit("description")] when: You just want to reduce the number of visible tools.


Best Practices

  1. Write clear instructions: Skills are powerful because of their guidance. Be specific about the workflow.

  2. Keep skills focused: A skill should represent one coherent workflow, not a grab-bag of functions.

  3. Reference only what's needed: Don't include every function—just the ones relevant to the workflow.

  4. Use documents wisely: Include documents that provide essential context, not everything tangentially related.

  5. Name skills as actions: "Research", "Deploy", "Review" are better than "ResearchSkill" or "SearchFunctions".

csharp
// Good: Focused workflow with clear dual-context instructions
[Skill]
public Skill BugInvestigation()
{
    return SkillFactory.Create(
        name: "Investigate Bug",
        description: "Systematically investigate and diagnose a bug",
        functionResult: null,  // Auto-generated: "Investigate Bug skill activated. Available functions: ReadFile, Log, Diff, CodeSearch"
        systemPrompt: @"
            BUG INVESTIGATION WORKFLOW:
            1. Reproduce the issue using the provided steps
            2. Search codebase for related error messages
            3. Check recent commits for relevant changes
            4. Identify root cause before suggesting fixes",
        "FileSystemTool.ReadFile",
        "GitTool.Log",
        "GitTool.Diff",
        "SearchTool.CodeSearch"
    );
}

// Bad: Vague, too broad, no real guidance
[Skill]
public Skill DoStuff()
{
    return SkillFactory.Create(
        name: "Do Stuff",
        description: "Various operations",
        functionResult: "Tools available.",
        systemPrompt: null,  // No workflow guidance!
        "Tool1.Func1", "Tool1.Func2", "Tool2.Func1",
        "Tool2.Func2", "Tool3.Func1"  // Too many unrelated functions
    );
}

Next Steps

Released under the MIT License.